package com.awei.study.dataStructure.queue;

import com.awei.study.dataStructure.queue.abs.DoubleEndQueue;

import java.util.Iterator;

/**
 * @Author liweilong
 * @Date 2023/5/24 11:22
 */
public class LinkQueue_DoubleEnd<E> implements DoubleEndQueue<E>,Iterable<E> {
    static class Node<E> {
        Node<E> prev;
        E value;
        Node<E> next;

        public Node(Node<E> prev, E value, Node<E> next) {
            this.prev = prev;
            this.value = value;
            this.next = next;
        }
    }

    Node<E> sentinel = new Node<>(null,null,null);
    int size = 0; //
    int capacity = Integer.MAX_VALUE;   //容量

    public LinkQueue_DoubleEnd(int capacity) {
        this.capacity = capacity;
        this.sentinel.next = sentinel;
        this.sentinel.prev = sentinel;
    }


    @Override
    public boolean offerHead(E value) {
        if(isFull()) return false;
        Node<E> prev = sentinel;
        Node<E> next = sentinel.next;
        Node<E> newHead = new Node<>(prev, value, next);
        prev.next = newHead;
        next.prev = newHead;
        size++;
        return true;
    }

    @Override
    public boolean offerTail(E value) {
        if(isFull()) return false;
        Node<E> next = sentinel;
        Node<E> prev = sentinel.prev;
        Node<E> newTail = new Node<>(prev, value, next);
        prev.next = newTail;
        next.prev = newTail;
        size++;
        return true;
    }

    @Override
    public E pollHead() {
        if(isEmpty()) return null;
        Node<E> prev = sentinel;
        Node<E> head = prev.next;
        Node<E> next = head.next;
        prev.next = next;
        next.prev = prev;
        size--;
        return head.value;
    }

    @Override
    public E pollTail() {
        if(isEmpty()) return null;
        Node<E> next = sentinel;
        Node<E> tail = next.prev;
        Node<E> prev = tail.prev;
        prev.next = next;
        next.prev = prev;
        size--;
        return tail.value;
    }

    @Override
    public E peekHead() {
        if(isEmpty()) return null;
        Node<E> prev = sentinel;
        Node<E> head = prev.next;
        return head.value;
    }

    @Override
    public E peekTail() {
        if(isEmpty()) return null;
        Node<E> next = sentinel;
        Node<E> tail = next.prev;
        return tail.value;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean isFull() {
        return size == capacity;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            Node<E> head = sentinel.next;
            @Override
            public boolean hasNext() {
                return head != sentinel;
            }

            @Override
            public E next() {
                E value = head.value;
                head = head.next;
                return value;
            }
        };
    }
}
